package main

import (
	"fmt"
	"log"
	"net"
	"sync"
	"time"

	"raft/rpc"
)

// User 用户结构
type User struct {
	ID   string `json:"id"`
	Name string `json:"name"`
	Age  int    `json:"age"`
}

// UserService 用户服务
type UserService struct {
	users map[string]*User
	mu    sync.RWMutex
}

func NewUserService() *UserService {
	return &UserService{
		users: make(map[string]*User),
	}
}

func (s *UserService) Name() string {
	return "UserService"
}

// Create 创建用户
func (s *UserService) Create(user User) (string, error) {
	s.mu.Lock()
	defer s.mu.Unlock()

	if user.ID == "" {
		return "", fmt.Errorf("user ID cannot be empty")
	}

	if _, exists := s.users[user.ID]; exists {
		return "", fmt.Errorf("user already exists")
	}

	s.users[user.ID] = &user
	return user.ID, nil
}

// Get 获取用户
func (s *UserService) Get(id string) (*User, error) {
	s.mu.RLock()
	defer s.mu.RUnlock()

	user, exists := s.users[id]
	if !exists {
		return nil, fmt.Errorf("user not found")
	}

	return user, nil
}

func startServer() {
	server := rpc.NewServer()
	userService := NewUserService()

	if err := server.RegisterService(userService); err != nil {
		log.Fatal(err)
	}

	listener, err := net.Listen("tcp", ":8080")
	if err != nil {
		log.Fatal(err)
	}
	defer listener.Close()

	log.Println("Server started on :8080")

	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Println("accept error:", err)
			continue
		}
		go server.ServeConn(conn)
	}
}

func runClient() {
	conn, err := net.Dial("tcp", "localhost:8080")
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	client := rpc.NewClient(conn)

	// 测试创建用户
	newUser := User{
		ID:   "123",
		Name: "Alice",
		Age:  30,
	}

	var userID string
	if err := client.Call("UserService.Create", newUser, &userID); err != nil {
		log.Fatal("Create error:", err)
	}
	log.Println("Created user ID:", userID)

	// 测试获取用户
	var retrievedUser User
	if err := client.Call("UserService.Get", "123", &retrievedUser); err != nil {
		log.Fatal("Get error:", err)
	}
	log.Printf("Retrieved user: %+v\n", retrievedUser)
}

func main() {
	go func() {
		time.Sleep(100 * time.Millisecond)
		runClient()
	}()

	startServer()
}
